<template>
  <div class="file-box">
    <div class="file-title">
      <div style="display: flex; align-items: flex-end">
        <el-select
          v-model="showFileIndex"
          filterable
          placeholder="请选择文件"
          class="!w-[400px]"
          popper-class="select_popper"
        >
          <el-option
            v-for="(item, index) in fileList"
            :key="index"
            :label="item.name"
            :value="index"
          >
            <div class="opiton-item">
              <div>{{ item.name || "--" }}</div>
              <div
                v-if="!['png', 'jpg'].includes(item.suffix)"
                class="flex ml-2"
              >
                <div
                  v-if="!['xls', 'xlsx'].includes(item.suffix)"
                  class="btn"
                  @click.stop="webPreview(item)"
                >
                  网页预览
                </div>
                <div class="btn ml-2" @click.stop="downFile(item)">
                  文件下载
                </div>
              </div>
            </div>
          </el-option>
        </el-select>
        <!-- <span class="img-tips">图片以及docx文档中的图片支持点击放大查看</span> -->
        <span class="img-tips">加载异常可点击‘文件下载’查看源文件</span>
      </div>
    </div>
    <div v-loading="loadingFile" class="file-content">
      <iframe
        v-if="
          ['pdf', 'doc', 'docx', 'ppt', 'pptx'].includes(currentFileData.suffix)
        "
        style="width: 100%; height: 99%"
        :src="currentFileData.fileUrl"
      />
      <VueOfficeExcel
        v-else-if="['xls', 'xlsx'].includes(currentFileData.suffix)"
        :src="currentFileData.fileUrl"
        style="width: 100%; height: 99%"
        @rendered="fileLoadFinish"
        @error="fileLoadFinish"
      />
      <el-image
        v-else-if="['png', 'jpg', 'gif'].includes(currentFileData.suffix)"
        style="padding: 15px; margin: auto"
        fit="cover"
        :src="currentFileData.fileUrl"
        :preview-src-list="[currentFileData.fileUrl]"
        @load="fileLoadFinish"
        @error="fileLoadFinish"
      />
    </div>
  </div>
</template>
<script setup>
import VueOfficeExcel from "@vue-office/excel";
import "@vue-office/excel/lib/index.css";
import { ref, watch } from "vue";

defineOptions({
  name: "FilePreview"
});

// 传值
const props = defineProps({
  fileData: {
    type: String,
    default: ""
  },
  fileIndex: {
    type: Number,
    default: 0
  }
});

const showFileIndex = ref(props.fileIndex);
const loadingFile = ref(false);
const currentFileData = ref({});
const isInit = ref(false);
const fileList = ref([]);
const filePreUrl = localStorage.getItem("fileUrl");

const fileLoadFinish = () => {
  if (!currentFileData.value.suffix) {
    return;
  }
  setTimeout(() => {
    loadingFile.value = false;
  }, 200);
};

// 下载文件
const downFile = file => {
  console.log("downFile", file);
  // window.open(item.originFileUrl);
  handleDownload(file);
};

// 下载文件
function handleDownload(file) {
  if (!file.originFileUrl) return;
  changeBlob(file.originFileUrl).then(res => {
    saveAs(res, file.name);
  });
}

function changeBlob(url) {
  return new Promise(resolve => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response);
      }
    };
    xhr.send();
  });
}

function saveAs(blob, filename) {
  var link = document.createElement("a");
  link.href = window.URL.createObjectURL(blob);
  link.download = filename;
  link.click();
}

// 网页预览
const webPreview = item => {
  // 判断类型 文档特殊处理
  if (["doc", "docx"].includes(item.suffix)) {
    window.open(item.fileUrl);
    return;
  } else if (item.suffix == "pdf") {
    loadFileBlob(item.fileUrl).then(blob => {
      let newBlob = new Blob([blob], {
        type: "application/pdf"
      });
      let href = window.URL.createObjectURL(newBlob);
      window.open(href);
    });
  }
};

// 加载文件
const loadFileData = async () => {
  loadingFile.value = true;
  if (fileList.value.length == 0) {
    currentFileData.value = {};
    loadingFile.value = false;
    return;
  }
  let tempData = fileList.value[showFileIndex.value];
  if (tempData.suffix == "pdf") {
    await loadFileBlob(tempData.fileUrl)
      .then(blob => {
        let newBlob = new Blob([blob], {
          type: "application/pdf"
        });
        let url = window.URL.createObjectURL(newBlob);
        tempData.fileUrl = url + "#navpanes=0"; // 关闭缩略图模式
      })
      .catch(() => {
        loadingFile.value = false;
      });
  } else if (["doc", "docx", "ppt", "pptx"].includes(tempData.suffix)) {
    tempData.fileUrl = `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(tempData.fileUrl)}`;
  }
  console.log("tempData", tempData);
  currentFileData.value = tempData;
  if (!["png", "jpg", "gif"].includes(tempData.suffix)) {
    loadingFile.value = false;
  }
};

function loadFileBlob(fileUrl) {
  return new Promise(resolve => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", fileUrl, true);
    xhr.responseType = "blob";
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response);
      }
    };
    xhr.onerror = () => {
      resolve();
    };
    xhr.send();
  });
}

const getJsonVal = str => {
  // 判断是否是json字符串
  let result = [];
  if (typeof str == "string") {
    try {
      result = JSON.parse(str);
    } catch (e) {
      // console.log('---isJSON_test-err: ', e)
    }
  }
  return result;
};

// 初始化显示
const setFileList = val => {
  let tempFileList = getJsonVal(val);
  fileList.value = tempFileList.map(v => {
    let url = filePreUrl + v.fileUrl;
    return {
      name: v.name,
      suffix: v.suffix,
      fileUrl: url,
      originFileUrl: url
    };
  });
  console.log("fileList", fileList);
};

watch(
  () => props.fileData,
  newValue => {
    if (newValue && !isInit.value) {
      // [{"name":"3.1.2.pdf","fileUrl":"/file/fetch/202501/dc3464c969f340288073e45b7bccbdfe.pdf","suffix":"pdf","source":1},
      // {"name":"导入价格模版.xls","fileUrl":"/file/fetch/202501/c8e89d0843bf4aed88bcab943c1c9efc.xls","suffix":"xls","source":1}]
      isInit.value = true;
      setFileList(newValue);
      loadFileData();
    }
  },
  { immediate: true }
);

watch(
  () => showFileIndex.value,
  () => {
    loadFileData();
  }
);
</script>
<style lang="scss" scoped>
.select_popper {
  z-index: 999999 !important;
}
.opiton-item {
  display: flex;
  justify-content: space-between;
  .btn {
    color: #409eff;
    font-size: 12px;
    cursor: pointer;
  }
}
.file-box {
  height: calc(100vh - 35vh);
  overflow-x: auto;
  border: 1px solid #efefef;
  position: relative;
  border-radius: 5px;
  margin-bottom: 15px;
  display: flex;
  flex-direction: column;
  .file-title {
    color: #0081ff;
    padding: 12px 12px 12px 15px;
    position: sticky;
    top: 0;
    background-color: #fff;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .img-tips {
      color: #e6a23c;
      margin: 0 15px;
    }
  }
  .file-content {
    flex: 1;
    display: flex;
    overflow: auto;
    position: relative;
    background-color: gray;
  }
  .opt-pdiv {
    position: sticky;
    left: 0;
    top: 0;
    z-index: 100;
    .opt-box {
      position: absolute;
      left: 10px;
      top: 10px;
      border-radius: 2px;
      border: 1px solid #eee;
      border-bottom: none;
      background-color: rgba(0, 0, 0, 0.5);
      background-color: #fff;
      .opt-img {
        padding: 5px;
        border-bottom: 1px solid #eee;
        text-align: center;
        cursor: pointer;
      }
    }
  }
}
.file-box.nobd {
  border: none;
}
</style>
